package com.ecoolex.discount.sales.core.manager;

import com.ecoolex.discount.sales.core.dao.YWBrandCateDAO;
import com.ecoolex.discount.sales.core.dao.YWBrandDAO;
import com.ecoolex.discount.sales.core.external.v2.pojo.GetBrandsResponse;
import com.ecoolex.discount.sales.entity.YWBrand;
import com.ecoolex.discount.sales.entity.YWBrandCate;
import com.ecoolex.discount.sales.entity.YWBrandCateExample;
import com.ecoolex.discount.sales.entity.YWBrandExample;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class YWBrandManager {
    @Autowired
    private YWBrandDAO dao;

    @Autowired
    private YWBrandCateDAO cateDAO;

    public void save(GetBrandsResponse.Brand brand) {
        String brandId = brand.getBrandId();
        String channelId = brand.getChannelId();
        YWBrandExample.Criteria criteria = YWBrandExample.newAndCreateCriteria().andChannelIdEqualTo(channelId).andBrandIdEqualTo(brandId);
        YWBrand ywBrand = dao.selectOneByExample(criteria.example());
        if (Objects.nonNull(ywBrand)) {
            BeanUtils.copyProperties(brand, ywBrand);
            ywBrand.setQueryLink(brand.getWebsite());
            ywBrand.setBrandId(brandId);
            if(Objects.nonNull(brand.getUpdateTime())){
                ywBrand.setLastModifiedTime(Date.from(Instant.ofEpochSecond(brand.getUpdateTime())));
            }
            ywBrand.setUpdateUser("system-admin");
            ywBrand.setUpdateTime(Date.from(Instant.now()));
            dao.updateByPrimaryKey(ywBrand);
            detectCategroyChange(brand.getCategories(),brandId,channelId);
        } else {
            ywBrand = new YWBrand();
            BeanUtils.copyProperties(brand, ywBrand);
            ywBrand.setQueryLink(brand.getWebsite());
            ywBrand.setBrandId(brand.getBrandId());
            if( 0 < brand.getUpdateTime()){
                ywBrand.setLastModifiedTime(Date.from(Instant.ofEpochSecond(brand.getUpdateTime())));
            }
            ywBrand.setStatus(1);
            ywBrand.setDeleted(YWBrand.NOT_DELETED);
            ywBrand.setCreateTime(Date.from(Instant.now()));
            ywBrand.setCreateUser("system-admin");
            ywBrand.setUpdateUser("system-admin");
            ywBrand.setUpdateTime(Date.from(Instant.now()));
            dao.insert(ywBrand);
            if (!CollectionUtils.isEmpty(brand.getCategories())) {
                List<YWBrandCate> brandCateSet = brand.getCategories().stream().distinct().map(item -> wrap(item,brandId,channelId)).collect(Collectors.toList());
                cateDAO.batchInsert(brandCateSet);
            }

        }
    }
    private YWBrandCate wrap(String cate,String brandId,String channelId){
        YWBrandCate ywBrandCate = new YWBrandCate();
        ywBrandCate.setBrandId(brandId);
        ywBrandCate.setChannelId(channelId);
        ywBrandCate.setCategroy(cate);
        ywBrandCate.setStatus(1);
        ywBrandCate.setDeleted(YWBrandCate.NOT_DELETED);
        ywBrandCate.setCreateTime(Date.from(Instant.now()));
        ywBrandCate.setCreateUser("system-admin");
        ywBrandCate.setUpdateUser("system-admin");
        ywBrandCate.setUpdateTime(Date.from(Instant.now()));
        return ywBrandCate;
    }

    /**
     * 检测品牌类别的差异变化
     * @param category
     * @param brandId
     */
    public void detectCategroyChange(List<String> category,String brandId,String channelId){
        YWBrandCateExample.Criteria criteria = YWBrandCateExample.newAndCreateCriteria().andChannelIdEqualTo(channelId).andBrandIdEqualTo(brandId);
        List<YWBrandCate> cateList = cateDAO.selectByExample(criteria.example());
        if (CollectionUtils.isEmpty(category)
                && CollectionUtils.isEmpty(cateList)){ //待更新的与已持久化的都为空时，不执行任何操作
            log.info("Brand:{} category is empty",brandId);
        }else {
            if (CollectionUtils.isEmpty(category)
                    && CollectionUtils.isNotEmpty(cateList)){ // 待更新的为空、已持久化的不为空时，则已持久化的全部标记为逻辑删除
                cateList.stream().filter(cate -> YWBrandCate.NOT_DELETED.equals(cate.getDeleted())).forEach(cate ->{
                    cate.setDeleted(YWBrandCate.IS_DELETED);
                    cateDAO.updateByPrimaryKeySelective(cate,YWBrandCate.Column.deleted);
                });
            }else if (CollectionUtils.isNotEmpty(category)
                    && CollectionUtils.isEmpty(cateList)){ // 待更新的为不为空、已持久化的空时，则待更新的全部插入
                List<YWBrandCate> brandCateSet = category.stream().distinct().map(item -> wrap(item,brandId,channelId)).collect(Collectors.toList());
                cateDAO.batchInsert(brandCateSet);
            }else {
                Map<String,YWBrandCate> cateMap = new HashMap<>(cateList.size());
                cateList.forEach(cate ->{
                    cateMap.put(cate.getCategroy(),cate);
                });
                Map<String,String> toSaveCateMap = new HashMap<>(category.size());
                category.forEach(cate ->{
                    toSaveCateMap.put(cate,cate);
                });
                cateMap.forEach((k,v) ->{
                    if(!toSaveCateMap.containsKey(k)){
                        v.setDeleted(YWBrandCate.IS_DELETED);
                        cateDAO.updateByPrimaryKeySelective(v,YWBrandCate.Column.deleted);
                    }else {
                        v.setDeleted(YWBrandCate.NOT_DELETED);
                        cateDAO.updateByPrimaryKeySelective(v,YWBrandCate.Column.deleted);
                    }
                    toSaveCateMap.remove(k);
                });
                toSaveCateMap.forEach((k,v) ->{
                    if(!cateMap.containsKey(k)){
                        cateDAO.insert(wrap(k,brandId,channelId));
                    }
                });
            }
        }

    }

    public List<YWBrand> getAllBrands(String channelId){
        YWBrandExample.Criteria criteria = YWBrandExample.newAndCreateCriteria() //
                .andStatusEqualTo(1) //
                .andDeletedEqualTo(YWBrand.NOT_DELETED) //
                .andChannelIdEqualTo(channelId) ;
       return dao.selectByExample(criteria.example());
    }
}
